using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// AB包资源管理器
/// </summary>
public class ABMgr : BaseManager<ABMgr>
{
    AssetBundle PCPackage;

    public ABMgr()
    {
        //加载平台主包
        //PCPackage = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + E_ABPackage.PC.ToString());
    }
    //AB包字典，将加载的AB包统一管理
    Dictionary<E_ABPackage, AssetBundle> ABDic = new Dictionary<E_ABPackage, AssetBundle>();
    /// <summary>
    /// 同步加载（根据资源名字加载，注意同名资源，不推荐使用）
    /// </summary>
    /// <param name="package">包名</param>
    /// <param name="res">资源名</param>
    /// <returns></returns>
    public Object LoadABResources(E_ABPackage package, string res)
    {
        LoadPackage(package);
        return ABDic[package].LoadAsset(res);
    }
    /// <summary>
    /// 同步加载（根据资源类型加载）
    /// </summary>
    /// <param name="package">报名</param>
    /// <param name="res">资源名</param>
    /// <param name="type">类型</param>
    /// <returns></returns>
    public Object LoadABResources(E_ABPackage package, string res, System.Type type)
    {
        LoadPackage(package);
        return ABDic[package].LoadAsset(res, type);
    }

    /// <summary>
    /// 同步加载(根据泛型加载)
    /// </summary>
    /// <param name="package">包名</param>
    /// <param name="res">资源名</param>
    /// <typeparam name="T">泛型类型</typeparam>
    /// <returns></returns>
    public T LoadABResources<T>(E_ABPackage package, string res) where T : Object
    {
        LoadPackage(package);
        return ABDic[package].LoadAsset<T>(res);
    }
    /// <summary>
    /// 异步加载（根据名字加载）
    /// </summary>
    /// <param name="package">包名</param>
    /// <param name="res">资源名</param>
    /// <param name="callBack">回调函数</param>
    public void LoadABResourcesRsync(E_ABPackage package, string res, UnityAction<Object> callBack)
    {
        IEnumerator ie = LoadResourcesbyIterator(package, res, callBack);
        MonoMgr.GetInstance().StartCoroutine(ie);
    }
    IEnumerator LoadResourcesbyIterator(E_ABPackage package, string res, UnityAction<Object> callBack)
    {
        LoadPackage(package);
        AssetBundleRequest abR = ABDic[package].LoadAssetAsync(res);
        yield return abR;
        callBack(abR.asset);
    }

    /// <summary>
    /// 异步加载(根据type加载)
    /// </summary>
    /// <param name="package">包名</param>
    /// <param name="res">资源名</param>
    /// <param name="type">类型</param>
    /// <param name="callBack">回调</param>
    public void LoadABResourcesRsync(E_ABPackage package, string res, System.Type type, UnityAction<Object> callBack)
    {
        IEnumerator ie = LoadResourcesbyIterator(package, res, type, callBack);
        MonoMgr.GetInstance().StartCoroutine(ie);
    }
    IEnumerator LoadResourcesbyIterator(E_ABPackage package, string res, System.Type type, UnityAction<Object> callBack)
    {
        LoadPackage(package);
        AssetBundleRequest abR = ABDic[package].LoadAssetAsync(res, type);
        yield return abR;
        callBack(abR.asset);
    }

    /// <summary>
    /// 异步加载（根据泛型加载）
    /// </summary>
    /// <param name="package">包名</param>
    /// <param name="res">资源名</param>
    /// <param name="callBack">回调</param>
    /// <typeparam name="T">泛型类型</typeparam>
    public void LoadABResourcesRsync<T>(E_ABPackage package, string res, UnityAction<T> callBack) where T : Object
    {
        IEnumerator ie = LoadResourcesbyIterator<T>(package, res, callBack);
        MonoMgr.GetInstance().StartCoroutine(ie);
    }
    IEnumerator LoadResourcesbyIterator<T>(E_ABPackage package, string Res, UnityAction<T> callBack) where T : Object
    {
        LoadPackage(package);
        AssetBundleRequest abR = ABDic[package].LoadAssetAsync<T>(Res);
        yield return abR;
        callBack(abR.asset as T);
    }


    /// <summary>
    /// 加载包，并查看包的依赖关系
    /// </summary>
    /// <param name="package"></param>
    void LoadPackage(E_ABPackage package)
    {
        //判断是否有该包
        if (!CheckPackageInDic(package))
        {
            //没有就加载该包
            //检查该包的依赖关系
            System.String[] packageString = CheckPackageRelation(package);
            if (packageString != null)
            {
                foreach (string packageName in packageString)
                {
                    if (packageName != null)
                    {
                        //将字符串强转为枚举
                        E_ABPackage e_ABPackage = (E_ABPackage)System.Enum.Parse(typeof(E_ABPackage), packageName);
                        //判断关联的包是否加载    
                        if (!CheckPackageInDic(e_ABPackage))
                        {
                            //加载资源包并加入Dic管理
                            ABDic.Add(e_ABPackage, AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + packageName));
                        }
                    }
                }
            }
            //加载资源包并入Dic管理
            ABDic.Add(package, AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + package));
        }
    }
    //查找包的依赖关系
    System.String[] CheckPackageRelation(E_ABPackage package)
    {
        //在主包中查看引用关系
        AssetBundleManifest ABManifest = PCPackage.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
        System.String[] strs = ABManifest.GetAllDependencies(Application.streamingAssetsPath + "/" + package.ToString());
        if (strs.Length > 0)
            return strs;
        else
            return null;
    }
    //查看字典中是否已经加载该包
    bool CheckPackageInDic(E_ABPackage package)
    {
        if (ABDic.ContainsKey(package))
            return true;
        else
            return false;
    }
}
